Part One: The Scene Graph


Part Two: The VRML Source Code (shareclick.wrl)

Here is the entire VRML 2.0 source code. Type (or paste) this code into a file called "shareclick.wrl".

#VRML V2.0 utf8

PROTO Sony_BindSharedNode[ 
  field SFNode transformNode 
  field SFNode scriptNode NULL
] {}

WorldInfo {
  title "VsServer"
  info ["VsServer:spiw.com:7009"]
}

#create object to share
DEF SharedObj Transform {
  children [
    DEF CLICKME TouchSensor {}
    DEF ObjShape Shape {
      appearance Appearance {
        material Material {diffuseColor 1 0 0}
      }
      geometry Box { }
    }
  ]
}

#create script for the object
DEF ScriptForSharedObj Script {
  field SFNode sharedobj USE SharedObj
  eventIn SFBool touched
  eventIn SFString rpc_touched
  eventIn SFString rpc_rotateBox
  url "shareclick.class"
}

#route mouse click to "touched" method
ROUTE CLICKME.isActive TO ScriptForSharedObj.touched

Sony_BindSharedNode {
   transformNode USE SharedObj
   scriptNode USE ScriptForSharedObj
}

Part Three: The Java Source Code (shareclick.java)

Here is the Java source code. Type or paste this into a file called "shareclick.java".

import vs.*;
import vrml.*;

public class shareclick extends Script {
   
  SFNode sharedObjNode = (SFNode)getField("sharedobj");
  Transform sharedObj = (Transform)sharedObjNode.getValue();

  // constructor
  public shareclick () {}
   
  // main class which receives mouse click events   
  public void touched (ConstSFBool flag, ConstSFTime time) {
    
    if(flag.getValue() == true)
      return;
      
    // if click was received at the master, propagate to everyone
    // else and make local change as well
    if(Vscp.amIMaster()) {
      Vscp.sendApplSpecificMsgWithDist(sharedObjNode, "rpc_rotateBox",
                                       "", Vscp.allClientsExceptMe);
      actualChangeBox();
    }
    else { 
    // click received at a client - inform master about this and 
    // let master take care of the rest
    Vscp.sendApplSpecificMsgWithDist(sharedObjNode, "rpc_touched", "",
                                     Vscp.responderOnly);
    }
  }

  // rpc_touched : executed at master in response to a click at any 
  // other client. Master now propagates to everyone else and also
  // does local change
  public void rpc_touched(ConstSFString dum1, ConstSFTime dum2) {
    Vscp.sendApplSpecificMsgWithDist(sharedObjNode, "rpc_rotateBox",
                                     "", Vscp.allClientsExceptMe);
    actualChangeBox();
  } 

  // rpc_rotateBox : executed at each client upon hearing from master
  // that a click was received at some client somewhere
  public void rpc_rotateBox(ConstSFString data, ConstSFTime time) {
    actualChangeBox();
  }

  // actualChangeBox : local change function whihc rotates the box about y axis
  // by 10 degrees
  public void actualChangeBox() {
    float [] axis = {0, 1, 0, 10};
    float [] center = {0, 0, 0};

    sharedObj.rotateAroundLineDegree(axis, center, sharedObj.modeRelative);
  }
}